#include<stdio.h>
//#include<Mesh/Mesh_Frame.h>
//#include<Mesh/lib_cell_Iterator.h>
#include<Mesh_IO/Mesh_IO.h>
//#include<Algorithm/Algorithm1.h>
//#include<Algorithm/Algorithm2.h>
#include<tool/libcell_tools_formats.h>
#include<tool/libcell_tools_view.h>
//#include<Algorithm/Harmonic.h>
//#include <Algorithm/Conformal.h>
#include<Algorithm/intersection_of_two_surfaces.h>

#include<tool/libcell_tools_octree.h>
#include<tool/libcell_tools_algorithm.h>
#include<Mesh/libcell_iterator.h>
#include <Algorithm/qem.h>
#include<Algorithm/mesh_bool.h>
#include<Mesh/libcell_iterator.h>
#include<libcell_macros.h>
#define _ReadOff_   LibCell_ReadOff_
#define _ReadCell_  LibCell_ReadCell_
#define _ReadPly_ LibCell_ReadPly_
#define quote lib_cell_quote
#define _WriteCell_ LibCell_WriteCell_
static inline void show_cell_data(template_c*c)
{
    if(c==NULL){return;}
    printf("cid:%d\n",c->id);
    for(int i=0;i<c->vertices_size;i++)
    {
        printf("%d %.9lf %.9lf %.9lf\n",c->vertices[i]->id,c->vertices[i]->point[0],c->vertices[i]->point[1],c->vertices[i]->point[2]);

    }
}
static Mesh* tail_cellular_network(Mesh* ce, Mesh* cy)
{

    Mesh2_Crossover_Point* mcp1 = (Mesh2_Crossover_Point*)malloc(sizeof(Mesh2_Crossover_Point));
    Mesh2_Crossover_Point* mcp2 = (Mesh2_Crossover_Point*)malloc(sizeof(Mesh2_Crossover_Point));
    mesh2_crossover_point_init(mcp1); mesh2_crossover_point_init(mcp2);
    template_c* c1=(template_c*)(ce->get_cellp(ce,1648));

    template_c* c2=(template_c*)(cy->get_cellp(cy,3844));
    show_cell_data(c1);show_cell_data(c2);

    Mesh* inter_curve = get_intersection_lines_of_two_meshs(ce, cy, mcp1, mcp2);
    printf("end get intersectin\n");
//     printf("here :%d %d\n", curve->num_v(curve), curve->num_f(curve));

    

    adjust_mesh_topology_of_cintersecting_curve(inter_curve, mcp1, mcp2);

    Int_RB_Tree* tree1=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
    int_rb_tree_init(tree1);
    Int_RB_Tree* tree2=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
    int_rb_tree_init(tree2);
    Int_RB_Tree* tree3=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
    int_rb_tree_init(tree3);
    Int_RB_Tree* tree4=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
    int_rb_tree_init(tree4);
    Int_RB_Tree* tree5=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
    int_rb_tree_init(tree5);
    Node* node_c=NULL;
    for(auto cit=ce->c_begin(ce);cit!=ce->c_end(ce);cit++)
    {
        node_c=node_overlying(node_c,quote(cit));
    }
    Mesh*nm= remesh_along_intersecting_curve(node_c,mcp1,inter_curve,
        tree2,tree3);
    _WriteOff_(nm,"nm.off");
   
    printf("begincut along*******************************8\n");
    cut_along_curve_mesh(nm,inter_curve,tree2,
        tree4,tree5);
    
    Mesh* nm1=NULL;int num1=0;
    Node*meshes= split_unicom_region2mesh(nm);
    for(Node* nit=meshes;nit!=NULL;nit=(Node*)(nit->Next))
    {
        Mesh* nm2=(Mesh*)(nit->value);
        if(num1<nm2->num_c(nm2))
        {
            num1=nm2->num_c(nm2);
            nm1=nm2;
        }
    }
    _WriteOff_(nm1,"nm1.off");
    
    //     //return curve;
//     printf("end adjust mesh topology\n");
//     double* bounds = mesh_compute_bounding_box(cy);


//     Node* node = NULL;

//     // int i=0;
//     // int end_i=15000;
//     for (auto cit = ce->c_begin(ce); cit != ce->c_end(ce); cit++)
//     {
       

//         double* cube = get_cube_from_cell(quote(cit));
//         //if (is_intersected_two_cube(bounds, &(bounds[3]), cube, &(cube[3])))
//         {
//             node = node_overlying(node, quote(cit));
//             //i++;

//         }
//         SAFE_FREE(cube);
//     }
//     Int_RB_Tree* tree = (Int_RB_Tree*)malloc(sizeof(Int_RB_Tree)), * tree1 = (Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
//     int_rb_tree_init(tree); int_rb_tree_init(tree1);

//     // for(auto it=mcp1->c2p->begin(mcp1->c2p);it.it!=NULL;it++)
//     // {
//     //     if(((template_v*)(it.second))->id==1846 )
//     //     {
//     //         printf("c id:%d\n",it.first);
//     //     }
//     // }
//     printf("begin remesh\n");
//     // return curve;

//     // mcp1->c2p->find(mcp1->c2p,)
//     //
//     nm = remesh_along_intersecting_curven(node, mcp1, curve, tree, tree1);


//     // nm = remesh_along_intersecting_curve(node, mcp1, curve, tree, tree1);
//     printf("end remesh\n");
//     // return nm;
//     for (auto vit = curve->v_begin(curve); vit != curve->v_end(curve); vit++)
//     {
//         template_v* v = (template_v*)(tree->find(tree, quote(vit)->id));
//         if (v == NULL)
//         {
//             //Crossover_Point* cp = (Crossover_Point*)(quote(vit)->prop);
//             //if (cp->scp[0].c != NULL)
//             //{

//             //    printf("c id :%d\n", cp->scp[0].c->id);
//             //    //printf("gengecuow1***** %d\n",node_size(quote(vit)->faces));
//             //}

//             if (quote(vit)->faces != NULL)
//             {
//                 printf("gengecuow***** %d\n", node_size(quote(vit)->faces));
//             }

//             Crossover_Point* cp = (Crossover_Point*)(quote(vit)->prop);
//             if (cp->scp[0].f != NULL)
//             {
//                 printf("not null f :id %d\n", cp->scp[0].f->id);
//             }
//             if (cp->scp[0].c != NULL)
//             {
//                 printf("not null c :id %d\n", cp->scp[0].c->id);
//             }
//             if (cp->scp[0].v != NULL)
//             {
//                 printf("not null v :id %d\n", cp->scp[0].v->id);
//             }
//             printf("cuowuu***********************%d %lf %lf\n", quote(vit)->id,
//                 quote(vit)->point[0], quote(vit)->point[1]);
//         }
//         // tree0->insert(tree0,v->id,quote(vit));
//     }

//     printf("end remesh\n");
//     //return nm;

//     Int_RB_Tree* tree3 = (Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
//     int_rb_tree_init(tree3);
//     Int_RB_Tree* tree2 = (Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
//     int_rb_tree_init(tree2);

//     Int_RB_Tree* tree0 = (Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
//     int_rb_tree_init(tree0);
//     printf("here2 :%d %d\n", curve->num_v(curve), curve->num_f(curve));

//     // for(auto vit =curve->v_begin(curve);vit!=curve->v_end(curve);vit++)
//     // {
//     //     template_v* v= (template_v*)(tree->find(tree,quote(vit)->id));
//     //     if(v==NULL)
//     //     {
//     //         printf("cuowuu\n");
//     //     }
//     //     tree0->insert(tree0,v->id,quote(vit));
//     // }
//     printf("begin cut \n");
//     printf("cut faces:%d %d %d\n", curve->num_f(curve),nm->num_c(nm),nm->num_f(nm));
//     printf("cut tree:%d\n",tree->size);
//     // cut_along_curve_mesh(nm,curve,tree,tree0,tree2,tree3);
//     cut_along_curve_mesh(nm, curve, tree, NULL, NULL, tree3);
//     for (auto vit=curve->v_begin(curve);vit!=curve->v_end(curve);vit++ )
//     {
//         free(quote(vit)->prop);

//     }
//     Mesh_free(curve);
//     free(curve);
    int_rb_tree_free(tree1);int_rb_tree_free(tree2);int_rb_tree_free(tree3);
    int_rb_tree_free(tree4);int_rb_tree_free(tree5);
    mesh2_crossover_point_free(mcp1); mesh2_crossover_point_free(mcp2);
//     printf("end cut\n");
    return NULL;
    //return nm;
}
void test_tools_algorithm()
{
    Mesh m,m1;
    Mesh_init(&m);Mesh_init(&m1);
    m.manifold_require=1;m1.manifold_require=1;
    m.dimension=2;m1.dimension=2;

    // _ReadOff_(&m,"boun_knife.off",3);
    // _ReadOff_(&m1,"xian4.off",3);

    // _ReadOff_(&m1,"qiu.off",3);
    // _ReadOff_(&m,"面片.off",3);

    // _ReadOff_(&m,"sphere.off",3);
    // _ReadOff_(&m1,"sphere1.off",3);
    // _ReadOff_(&m,"pm.off",3);
    // _ReadOff_(&m1,"spheres.off",3);
    _ReadOff_(&m1,"bound_knife.off",3);
    _ReadOff_(&m,"di.off",3);
    Mesh* nm=tail_cellular_network(&m,&m1);
   
    Mesh_free(&m); Mesh_free(&m1);
}

int main(int argc,char**argv)
{

    test_tools_algorithm();
   

    printf("end main\n");
    return 0;
}
